﻿using System;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using System.Collections.Generic;

namespace Z2.Core
{

	public class ItemBase : ObjectBase
	{

		#region Const

		private const int Grid = 48;
		public const string Group = "items";

		#endregion

		#region Members

		private static double TwoPi = 2 * Math.PI;
		private static List<SoundEffect> _pops;

		private ActionTimer m_anim;
		private double m_addY;
		private double m_angle;

		private int m_score;
		
		private bool m_isSwinging;
		private bool m_pickedUp;
		private Vector2 m_flyTo;
		private ParticleSettings m_particleSettings;

		#endregion

		#region Constructor

		static ItemBase()
		{
			_pops = new List<SoundEffect>();
			for (int i = 0; i < 4; ++i)
			{
				_pops.Add(SoundManager.Instance.LoadSound(string.Format("item{0}", i + 1)));
			}
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="sprite"><see cref="Sprite"/></param>
		protected ItemBase(Sprite sprite)
			: base(sprite)
		{
			this.IsStatic = true;
			this.IsSwinging = true;
			this.Light.LightSize = new Rectangle(0, 0, 
				3 * sprite.FrameWidth, 
				3 * sprite.FrameHeight);
			this.m_angle = RandomGenerator.Random.NextDouble();
			this.ParticleSettings = new ParticleSettings();
		}

		#endregion

		public override void Initialize()
		{
			base.Initialize();
			this.m_anim = new ActionTimer(10);
			this.m_anim.Enabled = true;
			this.InitialPosition = this.Position;
		}

		public override void Update()
		{
			if (!this.m_anim.Now()) return;

			float l = World.Current.GlobalLight;// *1.2F;
			//if (l > 1F) l = 1F;
			this.Light.Color = new Color(this.Light.Color, 255 - Convert.ToByte(255F * l));

			if (this.m_pickedUp)
			{
				this.Sprite.Visibility -= 0.04f;
				this.Position = new Vector2(
					this.Position.X + ((-(Camera.Instance.Position.X - 32) - this.Position.X) / 8.0f),
					this.Position.Y + ((-(Camera.Instance.Position.Y - 32) - this.Position.Y) / 8.0f));

				if(this.OnCameraPosition())
				{
					this.OnBeforeDestroy();
					this.Destroy();
				}

				return;
			}

			if (this.Move.Y != 0)
			{
				float sign = (this.Move.Y > 0 ? 1F : -1F);
				float speed = (this.Position.Y - (this.InitialPosition.Y + this.Move.Y)) / 8F;
				this.Position = new Vector2(this.Position.X, this.Position.Y + (speed * sign));
				if (Convert.ToInt32(this.Position.Y / 16) ==
					Convert.ToInt32((this.InitialPosition.Y + this.Move.Y) / 16)) this.Move = Vector2.Zero;
				this.m_addY = 0;
				this.m_angle = 0;
				return;
			}

			if (this.IsSwinging)
			{
				this.m_addY = Math.Sin(this.m_angle) * 10;

				this.m_angle += 0.1f;
				if (this.m_angle > ItemBase.TwoPi) this.m_angle = 0f;
			}
		}
		

		private bool OnCameraPosition()
		{
			return
				Convert.ToInt32(this.Position.X / Grid) == -Convert.ToInt32((Camera.Instance.Position.X - 32) / Grid)
				&& Convert.ToInt32(this.Position.Y / Grid) == -Convert.ToInt32((Camera.Instance.Position.Y - 32) / Grid);
		}

		protected static List<SoundEffect> Pops
		{
			get { return _pops; }
		}

		protected ParticleSettings ParticleSettings
		{
			get { return this.m_particleSettings; }
			set { this.m_particleSettings = value; }
		}

		public int Score
		{
			get { return this.m_score; }
			set { this.m_score = value; }
		}

		public bool IsPickedUp
		{
			get { return this.m_pickedUp; }
		}

		public bool IsSwinging
		{
			get { return this.m_isSwinging; }
			set { this.m_isSwinging = value; }
		}

		public override void Draw(SpriteBatch batch)
		{
			this.Sprite.Draw
			(
				batch,
				Vector2.Add
				(
					new Vector2(this.m_position.X, this.m_position.Y + (int)this.m_addY),
					Camera.Instance.Position
				)
			);
		}
		
		public override void DrawLight(SpriteBatch batch)
		{
			this.Light.DrawLight(batch, 
				Vector2.Add(new Vector2(this.m_position.X, this.m_position.Y + (int)this.m_addY), 
				Camera.Instance.Position), this.Sprite);
		}

		protected virtual void OnPickUp()
		{
		}

		protected virtual void OnBeforeDestroy()
		{
		}

		protected override void OnCollision(ref IntersectionResult result, ObjectBase obj)
		{
			if (obj is Player)
			{
				result = IntersectionResult.None;
				if (this.m_pickedUp) return;

				(obj as Player).Score += this.Score;
                FloatingText scoreText = new FloatingText(
                    Convert.ToString(this.Score), this.Position);
                World.Current.AddDraw(scoreText);
				this.m_score = 0;
                this.OnPickUp();
				this.CollisionRect = Rectangle.Empty;

				this.m_flyTo = Camera.Instance.Position;
				this.m_pickedUp = true;
			}
		}

	}
}
